package aigenx

// 我需要使用go实现一个SQL语句构建工具类, 下面是主要结构题，帮我按照这个要求生成常用的sql， 可以参考larvel的实现方式, 每个Clause都有自己的Builder方法实现SQl的处理.
// 我用columnClause举了个例子, 如果这个不太好你也可以优化

// type Builder struct {
// 	s        strings.Builder // 预处理SQL
// 	bindings []interface{}   // 参数绑定
// }

// func (builder *Builder) WriteString(s string, bindings ...any) {
// 	builder.s.WriteString(s)
// 	builder.bindings = append(builder.bindings, bindings...)
// }

// type QueryBuilder struct {
// 	table   string       // 主表
// 	columns columnClause // 列
// 	wheres  whereClause  // 查询条件
// 	joins   joinClause   // 连表配置
// 	groups  groupClause  // 分组
// 	orders  orderClause  // 排序
// 	having  havingClause // having
// 	limit   int          // 查询数据量
// 	offset  int          // 查询偏移量

// 	s strings.Builder // 预处理SQL
// }

// type ClauseInterface interface {
// 	BuilderSql(builder *Builder)
// }

// // Clause 基础子句
// type Clause struct {
// }

// type columnClause struct {
// 	column []string
// }

// func (clause *columnClause) Builder(builder *Builder) {
// 	// qb.s.Write("")
// }

import (
	"strings"
)

// Builder 基础构建器
type Builder struct {
	s        strings.Builder // 预处理SQL
	bindings []interface{}   // 参数绑定
}

func (b *Builder) WriteString(s string, bindings ...interface{}) {
	b.s.WriteString(s)
	b.bindings = append(b.bindings, bindings...)
}

func (b *Builder) GetSQL() string {
	return b.s.String()
}

func (b *Builder) GetBindings() []interface{} {
	return b.bindings
}

// ClauseInterface 子句接口
type ClauseInterface interface {
	Build(builder *Builder)
}

// QueryBuilder 查询构建器
type QueryBuilder struct {
	builder  Builder
	table    string       // 主表
	columns  ColumnClause // 列
	wheres   WhereClause  // 查询条件
	joins    JoinClause   // 连表配置
	groups   GroupClause  // 分组
	orders   OrderClause  // 排序
	having   HavingClause // having
	limit    int          // 查询数据量
	offset   int          // 查询偏移量
	distinct bool         // 是否distinct
}

// NewQueryBuilder 创建新的查询构建器
func NewQueryBuilder() *QueryBuilder {
	return &QueryBuilder{
		wheres: WhereClause{
			conditions: make([]whereCondition, 0),
		},
	}
}

// Table 设置表名
func (qb *QueryBuilder) Table(table string) *QueryBuilder {
	qb.table = table
	return qb
}

// Select 设置查询字段
func (qb *QueryBuilder) Select(columns ...string) *QueryBuilder {
	qb.columns.columns = columns
	return qb
}

// AddSelect 添加查询字段
func (qb *QueryBuilder) AddSelect(columns ...string) *QueryBuilder {
	qb.columns.columns = append(qb.columns.columns, columns...)
	return qb
}

// Distinct 设置distinct
func (qb *QueryBuilder) Distinct() *QueryBuilder {
	qb.distinct = true
	return qb
}

// Where 添加where条件
func (qb *QueryBuilder) Where(column string, operator string, value interface{}) *QueryBuilder {
	qb.wheres.conditions = append(qb.wheres.conditions, whereCondition{
		column:   column,
		operator: operator,
		value:    value,
		boolean:  "and",
	})
	return qb
}

// OrWhere 添加or where条件
func (qb *QueryBuilder) OrWhere(column string, operator string, value interface{}) *QueryBuilder {
	qb.wheres.conditions = append(qb.wheres.conditions, whereCondition{
		column:   column,
		operator: operator,
		value:    value,
		boolean:  "or",
	})
	return qb
}

// Join 添加join
func (qb *QueryBuilder) Join(table string, first string, operator string, second string) *QueryBuilder {
	qb.joins.joins = append(qb.joins.joins, join{
		table:    table,
		first:    first,
		operator: operator,
		second:   second,
		joinType: "inner",
	})
	return qb
}

// LeftJoin 添加left join
func (qb *QueryBuilder) LeftJoin(table string, first string, operator string, second string) *QueryBuilder {
	qb.joins.joins = append(qb.joins.joins, join{
		table:    table,
		first:    first,
		operator: operator,
		second:   second,
		joinType: "left",
	})
	return qb
}

// GroupBy 添加分组
func (qb *QueryBuilder) GroupBy(columns ...string) *QueryBuilder {
	qb.groups.columns = columns
	return qb
}

// OrderBy 添加排序
func (qb *QueryBuilder) OrderBy(column string, direction string) *QueryBuilder {
	qb.orders.orders = append(qb.orders.orders, order{
		column:    column,
		direction: direction,
	})
	return qb
}

// Having 添加having条件
func (qb *QueryBuilder) Having(column string, operator string, value interface{}) *QueryBuilder {
	qb.having.conditions = append(qb.having.conditions, havingCondition{
		column:   column,
		operator: operator,
		value:    value,
		boolean:  "and",
	})
	return qb
}

// Offset 设置偏移量
func (qb *QueryBuilder) Offset(offset int) *QueryBuilder {
	qb.offset = offset
	return qb
}

// Limit 设置限制数量
func (qb *QueryBuilder) Limit(limit int) *QueryBuilder {
	qb.limit = limit
	return qb
}

// ToSQL 生成SQL语句
func (qb *QueryBuilder) ToSQL() (string, []interface{}) {
	qb.buildSelect()
	qb.buildFrom()
	qb.buildJoins()
	qb.buildWheres()
	qb.buildGroups()
	qb.buildHaving()
	qb.buildOrders()
	qb.buildLimit()
	qb.buildOffset()

	return qb.builder.GetSQL(), qb.builder.GetBindings()
}

// 构建SELECT部分
func (qb *QueryBuilder) buildSelect() {
	qb.builder.WriteString("SELECT ")

	if qb.distinct {
		qb.builder.WriteString("DISTINCT ")
	}

	if len(qb.columns.columns) == 0 {
		qb.builder.WriteString("*")
	} else {
		qb.builder.WriteString(strings.Join(qb.columns.columns, ", "))
	}
}

// 构建FROM部分
func (qb *QueryBuilder) buildFrom() {
	if qb.table != "" {
		qb.builder.WriteString(" FROM ")
		qb.builder.WriteString(qb.table)
	}
}

// 构建JOIN部分
func (qb *QueryBuilder) buildJoins() {
	for _, join := range qb.joins.joins {
		qb.builder.WriteString(" ")
		qb.builder.WriteString(strings.ToUpper(join.joinType))
		qb.builder.WriteString(" JOIN ")
		qb.builder.WriteString(join.table)
		qb.builder.WriteString(" ON ")
		qb.builder.WriteString(join.first)
		qb.builder.WriteString(" ")
		qb.builder.WriteString(join.operator)
		qb.builder.WriteString(" ")
		qb.builder.WriteString(join.second)
	}
}

// 构建WHERE部分
func (qb *QueryBuilder) buildWheres() {
	if len(qb.wheres.conditions) > 0 {
		qb.builder.WriteString(" WHERE ")

		for i, condition := range qb.wheres.conditions {
			if i > 0 {
				qb.builder.WriteString(" ")
				qb.builder.WriteString(strings.ToUpper(condition.boolean))
				qb.builder.WriteString(" ")
			}

			qb.builder.WriteString(condition.column)
			qb.builder.WriteString(" ")
			qb.builder.WriteString(condition.operator)
			qb.builder.WriteString(" ?")
			qb.builder.bindings = append(qb.builder.bindings, condition.value)
		}
	}
}

// 构建GROUP BY部分
func (qb *QueryBuilder) buildGroups() {
	if len(qb.groups.columns) > 0 {
		qb.builder.WriteString(" GROUP BY ")
		qb.builder.WriteString(strings.Join(qb.groups.columns, ", "))
	}
}

// 构建HAVING部分
func (qb *QueryBuilder) buildHaving() {
	if len(qb.having.conditions) > 0 {
		qb.builder.WriteString(" HAVING ")

		for i, condition := range qb.having.conditions {
			if i > 0 {
				qb.builder.WriteString(" ")
				qb.builder.WriteString(strings.ToUpper(condition.boolean))
				qb.builder.WriteString(" ")
			}

			qb.builder.WriteString(condition.column)
			qb.builder.WriteString(" ")
			qb.builder.WriteString(condition.operator)
			qb.builder.WriteString(" ?")
			qb.builder.bindings = append(qb.builder.bindings, condition.value)
		}
	}
}

// 构建ORDER BY部分
func (qb *QueryBuilder) buildOrders() {
	if len(qb.orders.orders) > 0 {
		qb.builder.WriteString(" ORDER BY ")

		for i, order := range qb.orders.orders {
			if i > 0 {
				qb.builder.WriteString(", ")
			}

			qb.builder.WriteString(order.column)
			qb.builder.WriteString(" ")
			qb.builder.WriteString(order.direction)
		}
	}
}

// 构建LIMIT部分
func (qb *QueryBuilder) buildLimit() {
	if qb.limit > 0 {
		qb.builder.WriteString(" LIMIT ")
		qb.builder.WriteString(string(qb.limit))
	}
}

// 构建OFFSET部分
func (qb *QueryBuilder) buildOffset() {
	if qb.offset > 0 {
		qb.builder.WriteString(" OFFSET ")
		qb.builder.WriteString(string(qb.offset))
	}
}

// ColumnClause 列子句
type ColumnClause struct {
	columns []string
}

// WhereClause where子句
type WhereClause struct {
	conditions []whereCondition
}

type whereCondition struct {
	column   string
	operator string
	value    interface{}
	boolean  string
}

// JoinClause join子句
type JoinClause struct {
	joins []join
}

type join struct {
	table    string
	first    string
	operator string
	second   string
	joinType string
}

// GroupClause group子句
type GroupClause struct {
	columns []string
}

// OrderClause order子句
type OrderClause struct {
	orders []order
}

type order struct {
	column    string
	direction string
}

// HavingClause having子句
type HavingClause struct {
	conditions []havingCondition
}

type havingCondition struct {
	column   string
	operator string
	value    interface{}
	boolean  string
}
